﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OutlookDataGridView
{
	using OL = Microsoft.Office.Interop.Outlook;
	using System.Reflection;
	using System.Diagnostics;
	using System.Runtime.InteropServices;

	public partial class OutlookForm : Form
	{
		public OutlookForm()
		{
			InitializeComponent();
			this.SuspendLayout();
			InitializeTabs();
			this.ResumeLayout(true);
		}

		[DllImport("user32.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		static extern bool SetForegroundWindow(IntPtr hWnd);


		private const int fieldCount = 8;
		private Type[] dataType = new Type[fieldCount]
			{
				typeof(OL._AppointmentItem),
				typeof(OL._ContactItem),
				typeof(OL._DistListItem),
				typeof(OL._JournalItem),
				typeof(OL._MailItem),
				//typeof(OL._MobileItem), // TODO: used for both MMS and SMS!
				//typeof(OL._MobileItem),
				typeof(OL._NoteItem),
				typeof(OL._PostItem),
				typeof(OL._TaskItem)
			};

		private OL.OlItemType[] itemType = new OL.OlItemType[fieldCount]
			{
				(OL.OlItemType.olAppointmentItem),
				(OL.OlItemType.olContactItem),
				(OL.OlItemType.olDistributionListItem),
				(OL.OlItemType.olJournalItem),
				(OL.OlItemType.olMailItem),
				//(OL.OlItemType.olMobileItemMMS),
				//(OL.OlItemType.olMobileItemSMS),
				(OL.OlItemType.olNoteItem),
				(OL.OlItemType.olPostItem),
				(OL.OlItemType.olTaskItem)
			};

		private DataGridView[] dataGridView = new DataGridView[fieldCount];
		private System.Windows.Forms.BindingSource[] bindingSource = new BindingSource[fieldCount];
		private TabPage[] tabPage = new TabPage[fieldCount];

		private OL.Application _olApp;
		private OL.NameSpace _olNs;

		protected OL.Application OlApp
		{
			get
			{
				if (_olApp == null)
					_olApp = new OL.Application();
				return _olApp;
			}
		}

		protected OL.NameSpace OlNs
		{
			get
			{
				if (_olNs == null)
					_olNs = OlApp.GetNamespace("MAPI");
				return _olNs;
			}
		}

		private void InitializeTabs()
		{
			for (int i = 0; i < fieldCount; i++)
			{
				bindingSource[i] = new BindingSource();
				bindingSource[i].DataSource = dataType[i];

				dataGridView[i] = new DataGridView();
				dataGridView[i].DataSource = bindingSource[i];

				dataGridView[i].DataError +=
					(object sender, DataGridViewDataErrorEventArgs e) =>
					{
						e.ThrowException = false;
						Trace.WriteLine(e.Exception);
					};
				dataGridView[i].AllowUserToAddRows = false;
				dataGridView[i].AllowUserToDeleteRows = false;

				dataGridView[i].ReadOnly = true;

				tabPage[i] = new TabPage(itemType[i].ToString());
				tabControl1.TabPages.Add(tabPage[i]);

				tabPage[i].Size = tabControl1.Size;

				tabPage[i].Controls.Add(dataGridView[i]);
				dataGridView[i].Size = dataGridView[i].Parent.Size - new System.Drawing.Size(30, 30);

				dataGridView[i].AllowUserToOrderColumns = true;
			}
		}

		private void btnSelectFolder_Click(object sender, EventArgs e)
		{
			this.Cursor = Cursors.WaitCursor;

			OL.MAPIFolder selectedFolder = OlNs.PickFolder();
			SetForegroundWindow(this.Handle);

			if (selectedFolder == null)
				return;

			txtOutlookFolder.Text = selectedFolder.FolderPath;

			this.SuspendLayout();
			tabControl1.Controls.Clear();

			// no way to make this different without reflection
			int index = 0;

			bindingSource[index++].DataSource = new BindingList<OL._AppointmentItem>(selectedFolder.Items.OfType<OL._AppointmentItem>().ToArray());
			bindingSource[index++].DataSource = new BindingList<OL._ContactItem>(selectedFolder.Items.OfType<OL._ContactItem>().ToArray());
			bindingSource[index++].DataSource = new BindingList<OL._DistListItem>(selectedFolder.Items.OfType<OL._DistListItem>().ToArray());
			bindingSource[index++].DataSource = new BindingList<OL._JournalItem>(selectedFolder.Items.OfType<OL._JournalItem>().ToArray());
			bindingSource[index++].DataSource = new BindingList<OL._MailItem>(selectedFolder.Items.OfType<OL._MailItem>().ToArray());
			//bindingSource[index++].DataSource = new BindingList<OL._MobileItem>(selectedFolder.Items.OfType<OL._MobileItem>().ToArray());
			//bindingSource[index++].DataSource = new BindingList<OL._MobileItem>(selectedFolder.Items.OfType<OL._MobileItem>().ToArray());
			bindingSource[index++].DataSource = new BindingList<OL._NoteItem>(selectedFolder.Items.OfType<OL._NoteItem>().ToArray());
			bindingSource[index++].DataSource = new BindingList<OL._PostItem>(selectedFolder.Items.OfType<OL._PostItem>().ToArray());
			bindingSource[index++].DataSource = new BindingList<OL._TaskItem>(selectedFolder.Items.OfType<OL._TaskItem>().ToArray());

			int itemCount;
			for (int i = 0; i < fieldCount; i++)
			{
				itemCount = bindingSource[i].Count;
				if (itemCount > 0)
				{
					tabControl1.Controls.Add(tabPage[i]);
					tabPage[i].Text = string.Format("{0} ({1})", itemType[i].ToString(), itemCount);
					tabPage[i].Refresh();
				}
			}

			this.ResumeLayout(true);
			this.Cursor = Cursors.Default;

			Trace.WriteLine("Binding done");
		}


		private void chkBoxEdit_CheckedChanged(object sender, EventArgs e)
		{
			if (chkBoxEdit.Checked)
			{
				string text =
@"If you enable editing, it is possible to corrupt your Outlook Data.

Be carefully and just edit basics like subject or body!
";
				if (MessageBox.Show(text, "Do you really want to edit?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == System.Windows.Forms.DialogResult.Yes)
				{
					if (MessageBox.Show("Really sure what you do?", "Do you really want to edit?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == System.Windows.Forms.DialogResult.Yes)
						SetDataGridViewReadOnly(false);
					else
						chkBoxEdit.Checked = false;
				}
				else
				{
					chkBoxEdit.Checked = false;
				}
			}
			else
			{
				SetDataGridViewReadOnly(true);
			}
		}

		private void SetDataGridViewReadOnly(bool readOnly)
		{
			for (int i = 0; i < fieldCount; i++)
			{
				dataGridView[i].ReadOnly = readOnly;
			}
		}

		private void btnAbout_Click(object sender, EventArgs e)
		{
			MessageBox.Show("Please visit http://humergu.codeplex.com for information on the project", "OutlookDataGridView");
		}
	}
}
